#include "exti.h"

/************************************************************************
*函数名：Exti_Init
*函数功能：EXTI初始化配置函数
*函数参数：无
*函数返回值：无
*函数说明：
*				以按键（PA0、PE2、PE3、PE4）为例
*************************************************************************/
void Exti_Init(void)
{
	/*使能SYSCFG和GPIOA、GPIOE时钟*/
	RCC->APB2ENR |= (1<<14);//使能SYSCFG时钟
	RCC->AHB1ENR |= (1<<0);//使能GPIOA时钟
	RCC->AHB1ENR |= (1<<4);//使能GPIOE时钟

	/*配置GPIO控制器*/
	//模式寄存器——通用输入模式 00
	GPIOA->MODER &= ~(3<<0*2);
	GPIOE->MODER &= ~(3<<2*2 | 3<<3*2 | 3<<4*2);

	//上拉/下拉寄存器——无上下拉	00
	GPIOA->PUPDR &= ~(3<<0*2);
	GPIOE->PUPDR &= ~(3<<2*2 | 3<<3*2 | 3<<4*2);

	/*配置SYSCFG控制器*/
	SYSCFG->EXTICR[0] &= ~(15<<4*0);
	SYSCFG->EXTICR[0] |= (0<<4*0);//EXTI0选择PA0，0000

	SYSCFG->EXTICR[0] &= ~(15<<4*2);
	SYSCFG->EXTICR[0] |= (4<<4*2);//EXTI2选择PE2，0100

	SYSCFG->EXTICR[0] &= ~(15<<4*3);
	SYSCFG->EXTICR[0] |= (4<<4*3);//EXTI3选择PE3，0100

	SYSCFG->EXTICR[1] &= ~(15<<4*0);
	SYSCFG->EXTICR[1] |= (4<<4*0);//EXTI4选择PE4，0100

	/*配置EXTI控制器*/
	EXTI->IMR |= (1<<0|1<<2|1<<3|1<<4);//开启来自EXTI0/2/3/4线的中断请求
	EXTI->FTSR |= (1<<0);//允许下降沿触发EXTI0线中断
	EXTI->RTSR |= (1<<2|1<<3|1<<4);//允许上升沿触发EXTI2/3/4线中断

	/*开启NVIC中断*/
	//设置中断优先级
	NVIC_SetPriority(EXTI0_IRQn,NVIC_EncodePriority(7-2,0,1));//给EXTI0中断设置优先级为(0,1)
	NVIC_SetPriority(EXTI2_IRQn,NVIC_EncodePriority(7-2,0,1));//给EXTI2中断设置优先级为(0,1)
	NVIC_SetPriority(EXTI3_IRQn,NVIC_EncodePriority(7-2,0,1));//给EXTI3中断设置优先级为(0,1)
	NVIC_SetPriority(EXTI4_IRQn,NVIC_EncodePriority(7-2,0,1));//给EXTI4中断设置优先级为(0,1)
	//使能中断源
	NVIC_EnableIRQ(EXTI0_IRQn);
	NVIC_EnableIRQ(EXTI2_IRQn);
	NVIC_EnableIRQ(EXTI3_IRQn);
	NVIC_EnableIRQ(EXTI4_IRQn);
}


//全局变量
u8 Aflag = 0,Bflag = 0;
u32 count = 10;//店里的人数，初始设定为10人

/************************************************************************
*函数名：EXTIy_IRQHandler
*函数功能：EXTIy中断服务函数
*函数参数：无
*函数返回值：无
*函数说明：
*				y = 0,1,2,3,4,9_5
*************************************************************************/
void EXTI0_IRQHandler(void)
{
	if (EXTI->PR & (1<<0))//如果EXTI0线选择的IO口发生了边沿变化（PA0电平变化）
	{
		EXTI->PR |= (1<<0);//将PR的第0位写1可以将这一位清零
		if (GPIOA->IDR & (1<<0))//上升沿
		{
			printf("0 UP\n");
		}
		else								//下降沿
		{
			printf("0 DOWN\n");
		}
	}
}

void EXTI1_IRQHandler(void)
{

}

void EXTI2_IRQHandler(void)
{
	if (EXTI->PR & (1<<2))//如果EXTI2线选择的IO口发生了边沿变化（PE2电平变化）
	{
		EXTI->PR |= (1<<2);//将PR的第2位写1可以将这一位清零
		if (GPIOE->IDR & (1<<2))//上升沿
		{
			printf("2 UP\n");
		}
		else								//下降沿
		{
			printf("2 DOWN\n");
		}
	}
}

void EXTI3_IRQHandler(void)
{
	if (EXTI->PR & (1<<3))//如果EXTI3线选择的IO口发生了边沿变化（PE3电平变化）
	{
		EXTI->PR |= (1<<3);//将PR的第3位写1可以将这一位清零
		printf("3 UP\n");
		Aflag = 1;
		if (Aflag && Bflag)//先B后A，表示出
		{
			printf("Welcome next time\n");
			count--;
			printf("Number of persons:%d\n",count);
			Aflag = 0;
			Bflag = 0;
		}
	}
}

void EXTI4_IRQHandler(void)
{
	if (EXTI->PR & (1<<4))//如果EXTI4线选择的IO口发生了边沿变化（PE4电平变化）
	{
		EXTI->PR |= (1<<4);//将PR的第4位写1可以将这一位清零
		printf("4 UP\n");
		Bflag = 1;
		if (Aflag && Bflag)//先A后B，表示进
		{
			printf("Welcome\n");
			count++;
			printf("Number of persons:%d\n",count);
			Aflag = 0;
			Bflag = 0;
		}
	}
}

void EXTI9_5_IRQHandler(void)
{
	if (EXTI->PR & (1<<8))
	{
		EXTI->PR |= (1<<8);//将PR的第8位写1可以将这一位清零
		if (GPIOA->IDR & (1<<8))//上升沿
		{
			printf("UP\n");
		}
		else								//下降沿
		{
			printf("DOWN\n");
		}
	}
}
